home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / basic / qbnws104.zip / IQUEUE.ZIP / LQUEUE.ASM < prev    next >
Assembly Source File  |  1990-05-14  |  4KB  |  124 lines

  1.         page ,132
  2.         title   LQUEUE - Add an long-integer FIFO queue to BC/QB
  3.         subttl  Copyright 1990, Editing Services Co.
  4.         comment |
  5.  
  6. Implements a FIFO stack (circular queue, ring buffer) by adding five
  7. procedures to QB/BC: two SUBs and three FUNCTIONs.
  8. See LSTACK for a LIFO stack.
  9.  
  10.         DECLARE SUB      LQput (lval&)   'put an item in the queue
  11.         DECLARE FUNCTION LQget& ()       'get an item from the queue
  12.         DECLARE FUNCTION LQfree% ()      'TRUE if any room in queue
  13.         DECLARE FUNCTION LQavail% ()     'TRUE if anything in queue
  14.         DECLARE SUB      LQflush ()      'clear (empty) the queue
  15.         |
  16.                                                                         page +
  17.         .model medium, basic
  18.         .data
  19.  
  20. QPutPtr dw      0               ; pointer used for storing
  21. QGetPtr dw      0               ; pointer used for retrieving
  22.  
  23.         .code
  24.  
  25. Qsize   equ     256             ; size of buffer (one fewer available)
  26.  
  27. LQueue  dw      (Qsize * 2) dup (-1)
  28.                                                                         page +
  29. Querr:: INT     4               ; report "Overflow" to BASIC
  30.  
  31. LQput           PROC lval
  32.  
  33. ; Accepts a long-integer value and places it into the queue.
  34. ; Generates an Overflow Error in QB if there is no room in the queue.
  35.  
  36.         mov     bx, lval        ; get pointer to passed value
  37.         mov     ax, [bx]        ; get actual value, low part
  38.         mov     dx, 2[bx]
  39.         mov     bx, QPutPtr     ; get current head
  40.         inc     bx              ; increment it first
  41.         cmp     bx, Qsize       ; see if off end
  42.         jb      @f              ; no, still OK
  43.         xor     bx, bx          ; yes, circulate the pointer
  44. @@:     cmp     bx, QGetPtr     ; did we run into the tail?
  45.         je      querr           ; yes: the queue is FULL
  46.         mov     QPutPtr, bx     ; otherwise, save new head
  47.         shl     bx, 1           ; turn head into a word pointer
  48.         shl     bx, 1           ; then into a dword pointer
  49.         mov     LQueue[bx], ax  ; enqueue item, low part first
  50.         add     bx, 2
  51.         mov     LQueue[bx], dx  ; place high part into queue
  52.         ret
  53.  
  54. LQput           ENDP
  55.  
  56. LQget           PROC
  57.  
  58. ; Removes the oldest data item from the queue.
  59. ; Generates an Overflow Error if there are no values in the queue.
  60.  
  61.         mov     bx, QGetPtr     ; get current tail
  62.         cmp     bx, QPutPtr     ; is it at the head?
  63.         jz      querr           ; queue is empty: Overflow error
  64.         inc     bx              ; bump the tail pointer
  65.         cmp     bx, Qsize       ; off end?
  66.         jb      @f              ; no, continue
  67.         xor     bx, bx          ; yes, circulate 
  68. @@:     mov     QGetPtr, bx
  69.         push    bx              ; hold this thought
  70.         shl     bx, 1           ; turn QGetPtr into a word pointer
  71.         shl     bx, 1           ; then into a dword pointer
  72.         mov     ax, LQueue[bx]  ; retrieve low part value from stack
  73.         add     bx, 2
  74.         mov     dx, LQueue[bx]  ; retrieve high part
  75.         pop     bx              ; element number again
  76.         cmp     bx, QPutPtr     ; did we bump into the head?
  77.         jne     @f              ; no, still data left
  78.         mov     QPutPtr, 0      ; out of data, reset pointers
  79.         mov     QGetPtr, 0
  80. @@:     ret                     ; return retrieved value in DX:AX
  81.  
  82. LQget           ENDP
  83.  
  84. LQflush         PROC
  85.  
  86. ; Empty the queue by setting the head & tail equal
  87.  
  88.         mov     QPutPtr, 0
  89.         mov     QGetPtr, 0
  90.         ret
  91.  
  92. LQflush         ENDP
  93.  
  94. LQfree          PROC
  95.  
  96. ; Returns TRUE if there is any space left in the queue.
  97.  
  98.         mov     ax, QPutPtr
  99.         inc     ax
  100.         cmp     ax, Qsize
  101.         jb      @f
  102.         xor     ax, ax
  103. @@:     sub     ax, QGetPtr
  104.         jz      @f
  105.         mov     ax, -1
  106. @@:     ret
  107.  
  108. LQfree          ENDP
  109.  
  110. LQavail         PROC
  111.  
  112. ; Returns TRUE if there are any data items waiting in the queue.
  113.  
  114.         mov     ax, QGetPtr
  115.         sub     ax, QPutPtr
  116.         jz      @f
  117.         mov     ax, -1
  118. @@:     ret
  119.  
  120. LQavail         ENDP
  121.                                                                         page +
  122.         end
  123.  
  124.